#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>

#include <libusb.h>

#define EP_DATA_IN            (0x1|LIBUSB_ENDPOINT_IN)
#define EP_DATA_OUT           (0x2|LIBUSB_ENDPOINT_OUT)

static struct libusb_device_handle *devh = NULL;
static struct libusb_transfer *recv_bulk_transfer = NULL;

bool jlinkSendCommand(    void const* commandBuffer, uint32_t commandLength, void* resultBuffer, uint32_t resultBufferLength,uint32_t * transferred)
{
      int  r;
      r = libusb_bulk_transfer(devh, EP_DATA_OUT, (unsigned char *)commandBuffer, commandLength, transferred, 200);
      if(r<0) {perror("out"); return false;}
      if(!resultBufferLength)
              return true;

      // return !!ReadFile( resultBuffer, resultHeaderLength, nullptr, nullptr);
      r =libusb_bulk_transfer(devh, EP_DATA_IN, resultBuffer, resultBufferLength, transferred, 200);
      if(r!=0) perror("in");
      return r==0;
}

bool jlinkContinueReadResult(void* resultBuffer, uint32_t resultBufferLength,uint32_t * transferred)
{
      int  r;
      // return !!ReadFile( resultBuffer, resultLength, nullptr, nullptr);
      r = libusb_bulk_transfer(devh, EP_DATA_IN, resultBuffer, resultBufferLength, transferred, 200);
      if(r!=0) perror("in");
      return r==0;
}
int setup()
{
      int r = 1;

      r = libusb_init(NULL);
      if (r < 0) {
              fprintf(stderr, "failed to initialise libusb\n");
              goto out; 
      }

      devh = libusb_open_device_with_vid_pid(NULL, 0x1366, 0x0101);
      if (devh == NULL) {
              perror("busb_open_device_with_vid_pid");
              fprintf(stderr, "Could not find/open device\n");
              r=-1;
              goto out;
      }

      r = libusb_claim_interface(devh, 0);
      if (r < 0) {
              perror("libusb_claim_interface");
              fprintf(stderr, "usb_claim_interface error %d\n", r);
              goto out;
      }
      printf("claimed interface\n");
out:
      return r;
}

void cleanup()
{
    if(devh){
        libusb_release_interface(devh, 0);
        libusb_close(devh);
    
    }
    libusb_exit(NULL);
}

